#include <mono/common/string.h>
#include <iomanip>
#include <cstring>
#include <cstdio>

namespace mono {

std::string hex_encode(const void *data, size_t size)
{
    const unsigned char* const cdata
        = static_cast<const unsigned char* const>(data);

    std::string out;
    out.resize(size * 2);

    static const char xdigits[16] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };

    std::string::iterator oi = out.begin();
    for (const unsigned char* si = cdata; si != cdata + size; ++si)
    {
        *oi++ = xdigits[(*si & 0xF0) >> 4];
        *oi++ = xdigits[(*si & 0x0F)];
    }

    return out;

}

std::string hex_decode(const void *data, size_t size)
{
	  std::string result;
	  result.reserve(size+1);
	  const unsigned char *buff = static_cast<const unsigned char*>(data);
	  const unsigned char *end = static_cast<const unsigned char*>(data) + size;
	  while (*buff > '\0' && *buff <= ' ') {
			  buff++;
	  }
	  
	  while (buff != end) {

	  unsigned char num = 0;
	  unsigned char c = *(buff++);
	  if (c >= '0' && c <= '9') {
		  num = c - '0';
	  } else if (c >= 'a' && c <= 'f') {
		  num = c - 'a' + 10;
	  } else if (c >= 'A' && c <= 'F') {
		  num = c - 'A' + 10;
	  } else if (c == '\0') {
		   break;
	  }
	  c = *(buff++);
	  if (c >= '0' && c <= '9') {
		  num = num * 0x10 + c - '0';
	  } else if (c >= 'a' && c <= 'f') {
		  num = num * 0x10 + c - 'a' + 10;
	  } else if (c >= 'A' && c <= 'F') {
		  num = num * 0x10 + c - 'A' + 10;
	  } else if (c == '\0') {
		  result.append(1, (char)num);
		   break;
	  }
		  result.append(1,(char)num);
	}
	
	
	return result;
	
}

}

